

import bpy
from bpy.types import Header, Menu, Panel

import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类
import 全局控制.Node.插座.bl_插座基类 as 插件基类

from 节点.Core import bl_节点构建模板
from 节点.Core import bl_UI配色

from 全局控制.Node.节点数据类型 import bl_集合数据类型





import 物体.物体管理.物体数据 as 网格数据
#from 物体.物体管理 import engine_取场景物体属性
from 物体.物体管理 import engine_物体创建

import engine.initLIB.load_dll as engineLib
import ctypes

import pdb






engineLib.flexCAPI.f_创建取场景物体节点.restype = ctypes.c_bool
engineLib.flexCAPI.f_创建取Bl集合节点.restype = ctypes.c_bool







E_物体类型枚举 = [
	("MESH", "MESH", "", 0),
	("CURVE", "CURVE", "", 1),
	("SURFACE", "SURFACE", "", 2),
	("META", "META", "", 3),
	("EMPTY", "EMPTY", "", 4),
	("GPENCIL", "GPENCIL", "", 5),
	("CAMERA", "CAMERA", "", 6),
	("LIGHT", "LIGHT", "", 7),
	("SPEAKER", "SPEAKER", "", 8),
	("LIGHT_PROBE", "LIGHT_PROBE", "", 9),
]


E_灯光类型枚举 = [
	("None",	"所有", "", '', 0),
	("POINT",	"点光源", "", 'LIGHT_POINT', 1),
	("SUN",		"太阳光", "", 'LIGHT_SUN', 2),
	("SPOT",	"聚光灯", "", 'LIGHT_SPOT', 3),
	("AREA",	"区域光", "", 'LIGHT_AREA', 4),
]

#‘WINDOW’, ‘HEADER’, ‘CHANNELS’, ‘TEMPORARY’, ‘UI’, ‘TOOLS’, ‘TOOL_PROPS’, ‘PREVIEW’, ‘HUD’, ‘NAVIGATION_BAR’, ‘EXECUTE’, ‘FOOTER’], default ‘HEADER’

'''class C_过滤面板(Panel):
	bl_space_type = 'NODE_EDITOR'
	bl_region_type = 'UI'
	bl_label = "物体过滤"
	
	m_Node = bpy.props.StringProperty()
	m_Tree = bpy.props.StringProperty()
	def draw(self, context):
		layout = self.layout
		#DopesheetFilterPopoverBase.draw_generic_filters(context, layout)
		node = bpy.data.node_groups[self.m_Tree].nodes[self.m_Node]
		layout.separator()
		layout.prop(node, 'm_模型')
		layout.prop(node, 'm_灯光')
		layout.prop(node, 'm_相机')
		layout.prop(node, 'm_曲线')
		layout.separator()
		if node.m_灯光 :
			layout.prop(node, 'm_光类')'''






def f_节点数据即时更新(self, context):
	if context : self.f_update(context)


class C_过滤参数(object):
	m_模型 = bpy.props.BoolProperty(default=True, update=f_节点数据即时更新)
	m_虚拟 = bpy.props.BoolProperty(default=True, update=f_节点数据即时更新)
	m_曲线 = bpy.props.BoolProperty(default=True, update=f_节点数据即时更新)
	m_相机 = bpy.props.BoolProperty(default=True, update=f_节点数据即时更新)
	m_灯光 = bpy.props.BoolProperty(default=True, update=f_节点数据即时更新)
	m_光类 = bpy.props.EnumProperty(items=E_灯光类型枚举, default='SUN', update=f_节点数据即时更新)

	def f_过滤Draw(self, context, layout):
		grid = layout.grid_flow(row_major=True, columns=2, align=True)
		grid.prop(self, 'm_模型')
		grid.prop(self, 'm_灯光')
		grid.prop(self, 'm_虚拟')
		grid.prop(self, 'm_相机')
		grid.prop(self, 'm_曲线')
		layout.separator()
		if self.m_灯光 :
			layout.props_enum(self, 'm_光类')
			#layout.prop_menu_enum(self, 'm_光类')
			#layout.prop(self, 'm_光类')

	def f_过滤(self, obj):
		if self.m_模型 and obj.type == 'MESH':
			return obj
		elif self.m_灯光 and obj.type == 'LIGHT':
			if self.m_光类 != "None":
				if obj.data.type == self.m_光类:
					return obj
			else : return obj
		elif self.m_虚拟 and obj.type == 'EMPTY':
			return obj
		elif self.m_相机 and obj.type == 'CAMERA':
			return obj
		
		return None 

	

def f_物体数量update(self, context):
	差数 = len(self.m_Value) - self.m_物体_count
	#print('差数 = ', 差数)
	if 差数 > 0 :
		for i in range(差数):
			self.m_Value.remove(len(self.m_Value)-1)
	else:
		差数 = -差数
		for i in range(差数):
			self.m_Value.add()



class C_Node_物体组(基类.C_SN_基类):
	bl_dname = 'bl_node_物体组'
	bl_label = '物体组'

	m_Value = bpy.props.CollectionProperty(type=bl_集合数据类型.C_物体组元素)
	m_物体_count = bpy.props.IntProperty(update=f_物体数量update, min=0)
	def init(self, context):
		super(C_Node_物体组, self).f_init(context)
		self.outputs.new('C_NodeSocket_物体', name='物体')
		
		
	def draw_buttons(self, context, layout):
		layout.prop(self, "m_物体_count", text="count")
		col = layout.box()
		col = col.column()
		for c in self.m_Value:
			col.prop(c, "value", text="")

	def f_数据拷贝到输出插座中(self):
		输出插座 = self.outputs['物体']
		
		objs = []
		for c in self.m_Value:
			obj = c.value
			if obj != None:
				objs.append(obj)
		
		输出插座.f_setData(objs)

	
	def f_input插座Update(self, input插座, 上层Output=None):
		if input插座.name == '_>' :
			if 上层Output.f_getData() :
				self.f_数据拷贝到输出插座中()
			else:
				self.outputs['物体'].f_clear()
		super(C_Node_物体组, self).f_input插座Update(input插座, 上层Output)
		

	def f_update(self, 是否向下传递=False, input插座=None):
		输出插座 = self.outputs['物体']
		#insocket = self.inputs['_>']
		#print('insocket.is_linked = ', insocket.is_linked, insocket.f_getData())
		'''if insocket.is_linked and insocket.f_getData() == False:
			输出插座.f_clear()
		else:'''
		objs = []
		for c in self.m_Value:
			obj = c.value
			if obj != None:
				objs.append(obj)
		
		输出插座.f_setData(objs)
		#print('objs = ', 输出插座.f_getData())
		#pdb.set_trace()
		super(C_Node_物体组, self).f_update(是否向下传递, input插座)
class C_NODE_MENU_物体组(bpy.types.Operator):
	bl_idname = 'node.global_node_objects'
	bl_label = '物体组'
	bl_options = {'REGISTER', 'UNDO'}
	
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_物体组', use_transform=True)
		return {'FINISHED'}


















def f_打包bl对象为内部数据(self, 是否导入引擎):
	if 是否导入引擎 : self.m_Value.m_物体ID = engine_物体创建.f_添加物体到引擎(self.m_Value)
	data = (list(self.m_Value.name), self.m_Value.m_物体ID, bpy.data.objects[self.m_Value.name])
	return data





def f_物体节点指向物体update(self, context):
	#print('*************f_set_物体节点指向物体**************', self.m_Value)
	if self.m_Value != None :
		self.m_Value.m_物体ID = engine_物体创建.f_添加物体到引擎(self.m_Value, 构建数据=False)
		#print('self.m_Value.m_物体ID = ', bpy.data.objects, self.m_Value.m_物体ID)
		#data = (list(self.m_Value.name), self.m_Value.m_物体ID, bpy.data.objects[self.m_Value.name])
		data = (list(self.m_Value.name), 
				self.m_Value.m_物体ID, self.m_Value, 
				tuple(self.m_Value.location), 
				tuple(self.m_Value.rotation_euler), 
				tuple(self.m_Value.scale))
		engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));
	else:
		data = ([], -1, 0)

	if context :
		self.id_data.f_节点数据更新_更新树([self])
	

def f_set_物体节点指向物体(self, value):
	self.m_Value = value
	

class C_Node_物体(基类.C_Node_基类):
	bl_dname = 'bl_node_物体'
	bl_label = '物体'

	m_Value = bpy.props.PointerProperty(type=bpy.types.Object, update=f_物体节点指向物体update)
	m_是否导入引擎 = bpy.props.BoolProperty(default=False, update=f_物体节点指向物体update)
	#m_加入引擎 = bpy.props.BoolProperty()
	def init(self, context):
		super(C_Node_物体, self).f_init(context)
		self.outputs.new('C_Socket_物体', name='物体')
		
		self.outputs.new('C_Socket_Vec3', name='移动')
		self.outputs.new('C_Socket_Vec3', name='旋转')
		self.outputs.new('C_Socket_Vec3', name='缩放')

		self.outputs.new('C_Socket_物体数据', name='数据')
		#执行DLL函数
		self.f_toCPP(self.id_data)
		
	#def copy(self, node):
	#	self.f_toCPP()
	def f_toCPP(self, tree):
		新创建 = engineLib.flexCAPI.f_创建取场景物体节点(ctypes.c_wchar_p(tree.name), ctypes.c_wchar_p(self.name), self.f_getPyObject(tree));
		#print('C_Node_物体 ======= ', 新创建, tree)
		if 新创建 :
			self.use_custom_color = True
			self.color = bl_UI配色.g_物体类节点颜色
		#else:
		f_物体节点指向物体update(self, context=None)
		#print('f_物体节点指向物体update ======= ', tree)
		
	def draw_buttons(self, context, layout):
		layout.prop(self, "m_Value", text="")
		layout.prop(self, "m_是否导入引擎", text="导入引擎")
		#layout.popover(panel="C_过滤面板", text="", icon='FILTER')
		
		

class C_NODE_MENU_取物体(bpy.types.Operator):
	bl_idname = 'node.global_node_get_object'
	bl_label = '取物体'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		node = bpy.ops.node.add_node(type='C_Node_物体', use_transform=True)
		print('create node = ', node)
		return {'FINISHED'}






















#15873262931






















def f_物体集合_update(self, context):
	if self.m_集合 == None : return
	data = []
	for obj in list(self.m_集合.objects) :
		obj = self.f_过滤(obj)
		if obj :
			obj.m_物体ID = engine_物体创建.f_添加物体到引擎(obj)
			objData = (
				list(obj.name), obj.m_物体ID, bpy.data.objects[obj.name], 
				tuple(obj.location), 
				tuple(obj.rotation_euler), 
				tuple(obj.scale)
			)
			data.append( objData )
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));
	
	if context :
		self.id_data.f_节点数据更新_更新树([self])

class C_Node_取集合物体(基类.C_Node_基类, C_过滤参数):
	bl_dname = 'bl_node_取集合物体'
	bl_label = '取集合物体'
	
	m_集合 = bpy.props.PointerProperty(type=bpy.types.Collection)
	m_是否导入引擎 = bpy.props.BoolProperty(default=False, update=f_物体集合_update)
	m_递归 = bpy.props.BoolProperty(update=f_物体集合_update)
	def init(self, context):
		super(C_Node_取集合物体, self).f_init(context)
		self.outputs.new('C_Socket_物体_Array1D', name='物体集')

		self.outputs.new('C_Socket_Vec3_Array1D', name='移动')
		self.outputs.new('C_Socket_Vec3_Array1D', name='旋转')
		self.outputs.new('C_Socket_Vec3_Array1D', name='缩放')

		self.outputs.new('C_Socket_物体数据_Array1D', name='数据')
		self.f_toCPP(self.id_data)
		
	def draw_buttons(self, context, layout):
		#行 = layout.split(factor=[0.8,0.2])
		layout.prop(self, "m_集合", text="集合")
		行 = layout.row()
		C_过滤参数.f_过滤Draw(self=self, context=context, layout=layout)
		#item = 行.popover(panel="C_过滤面板", text="类型过滤", icon='FILTER')
		#item.m_Tree = self.id_data.name
		#item.m_Node = self.name
		行.prop(self, "m_递归") #, icon_only=True
		#行.prop(self, "m_是否导入引擎") #, icon_only=True
		
	def f_toCPP(self, tree):
		新创建 = engineLib.flexCAPI.f_创建取Bl集合节点(ctypes.c_wchar_p(tree.name), ctypes.c_wchar_p(self.name), self.f_getPyObject(tree));
		if 新创建 :
			self.use_custom_color = True
			self.color = bl_UI配色.g_内部节点颜色
		else:
			f_物体集合_update(self, None)

	def f_update(self, context=None):
		f_物体集合_update(self, context)
		print('mbt')
		
		
class C_NODE_MENU_取集合物体(bpy.types.Operator):
	bl_idname = 'node.global_node_get_collection_objects'
	bl_label = '取集合物体'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_取集合物体', use_transform=True)
		return {'FINISHED'}



















def f_物体组容器元素_update(self, context):
	print('f_物体组容器元素_update = ', self, self.node)
	if self.node:
		tree = bpy.data.node_groups[self.tree]
		node = tree.nodes[self.node]

		f_自选物体_update(node, context)

	if context :
		tree.f_节点数据更新_更新树([node])
	

class C_物体组容器元素(bpy.types.PropertyGroup):
	value = bpy.props.PointerProperty(type=bpy.types.Object, update=f_物体组容器元素_update)
	tree = bpy.props.StringProperty()
	node = bpy.props.StringProperty()
	
def f_自选物体_update(self, context):
	f_物体数量update(self, bpy.context)
	data = []
	for obj in self.m_Value:
		obj.tree = self.id_data.name
		obj.node = self.name
		#print('f_自选物体_update ', obj.tree, obj.node)
		if obj.value :
			data.append(
				(obj.value.m_物体ID, list(obj.value.name), obj.value,
				tuple(obj.value.location), 
				tuple(obj.value.rotation_euler), 
				tuple(obj.value.scale)
				)
			)
		#print('f_自选物体_update, ', data)
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));
	
	if context:
		self.id_data.f_节点数据更新_更新树([self])

class C_Node_自选物体集(基类.C_Node_基类):
	bl_dname = 'bl_node_自选物体集'
	bl_label = '自选物体集'
	
	m_Value = bpy.props.CollectionProperty(type=C_物体组容器元素)
	m_物体_count = bpy.props.IntProperty(update=f_自选物体_update, min=0)
	def init(self, context):
		super(C_Node_自选物体集, self).f_init(context)
		self.outputs.new('C_Socket_物体_Array1D', name='物体集')

		self.outputs.new('C_Socket_Vec3_Array1D', name='移动')
		self.outputs.new('C_Socket_Vec3_Array1D', name='旋转')
		self.outputs.new('C_Socket_Vec3_Array1D', name='缩放')

		self.outputs.new('C_Socket_物体数据_Array1D', name='数据')
		self.f_toCPP(self.id_data)
		
	def draw_buttons(self, context, layout):
		layout.prop(self, "m_物体_count", text="count")
		col = layout.box()
		col = col.column()
		for c in self.m_Value:
			col.prop(c, "value", text="")
			#c.tree = self.id_data.name
			#c.node = self.name
	def f_toCPP(self, tree):
		print('cj C_Node_自选物体集----------------------------------------')
		新创建 = engineLib.flexCAPI.f_创建自取物体节点(ctypes.c_wchar_p(tree.name), ctypes.c_wchar_p(self.name), self.f_getPyObject(tree));
		if 新创建 :
			f_自选物体_update(self, None)

			self.use_custom_color = True
			self.color = bl_UI配色.g_物体类节点颜色
			
	def f_update(self):
		f_自选物体_update(self, None)
		
		
class C_NODE_MENU_自选物体集(bpy.types.Operator):
	bl_idname = 'node.node_optional_objects'
	bl_label = '自选物体集'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_自选物体集', use_transform=True)
		return {'FINISHED'}













classes = (
	C_Node_物体组,
	C_NODE_MENU_物体组,
	
	C_Node_物体,
	C_NODE_MENU_取物体,
	
	C_Node_取集合物体,
	C_NODE_MENU_取集合物体,


	C_物体组容器元素,
	C_Node_自选物体集,
	C_NODE_MENU_自选物体集,

)

def register():
	for c in classes:
		bpy.utils.register_class(c)
		
def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)




